﻿using AutoMapper;
using Chat_IService;
using Chat_Model;
using Chat_Model.ViewModel;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Caching.Memory;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Chat_WebApi.Controllers.v1
{
    [Route("/api/v1/[controller]")]
    [ApiController]
    //[Authorize]
    public class TalkController : BaseController
    {
        private readonly ILarUsersService _larUsersService;
        private readonly ILarUsersFriendsService _larUsersFriendsService;
        private readonly IMapper _mapper;
        private readonly ILarTalkListService _larTalkListService;
        private readonly IHubContext<SignalRHub> _hubContext;
        private readonly IMemoryCache _cache;
        private readonly ILarTalkRecordsService _larTalkRecordsService;
        public TalkController(
            IHubContext<SignalRHub> hubClients,
            IMemoryCache memoryCache,
            ILarUsersService larUsersService,
            IMapper mapper,
            ILarTalkListService larTalkListService,
            ILarTalkRecordsService larTalkRecordsService,
            ILarUsersFriendsService larUsersFriendsService
            )
        {
            this._larUsersService = larUsersService;
            this._mapper = mapper;
            this._larTalkListService = larTalkListService;
            this._hubContext = hubClients;
            this._cache = memoryCache;
            this._larTalkRecordsService = larTalkRecordsService;
            this._larUsersFriendsService = larUsersFriendsService;
        }
        #region 消息相关接口

        /// <summary>
        /// 发送文本消息接口.
        /// </summary>
        /// <returns><placeholder>A <see cref="Task"/> representing the asynchronous operation.</placeholder></returns>
        [HttpPost("message/text")]
        public async Task<MessageModel<object>> Text([FromBody] TalkTextParam param)
        {
            if (param.Receiver_Id == 0 || param.Talk_Type == 0) return new MessageModel<object>() { Code = 305 };
            int uid = this._larUsersService.GetUserId();
            LarTalkRecords model = new LarTalkRecords
            {
                MsgType = 1,
                TalkType = param.Talk_Type,
                UserId = uid,
                ReceiverId = param.Receiver_Id,
                Content = param.Text,
            };
            model.Id = this._larTalkRecordsService.InsertReturnIdentity(model);

            string connectionId = this._cache.Get("re_" + param.Receiver_Id)?.ToString();
            if (!string.IsNullOrWhiteSpace(connectionId))
            {
                model.LarUsersFriends = await this._larUsersFriendsService.GetSingleAsync(x => x.UserId == param.Receiver_Id && x.FriendId == uid);
                model.LarUsers = await this._larUsersService.GetSingleAsync(x => x.Id == param.Receiver_Id);
                model.LarTalkList = await this._larTalkListService.GetSingleAsync(x => x.UserId == param.Receiver_Id && x.ReceiverId == uid);
                if (model.LarTalkList == null)
                {
                    LarTalkList larTalkList = new LarTalkList()
                    {
                        TalkType = param.Talk_Type > 0 ? param.Talk_Type : (byte)1,
                        UserId = param.Receiver_Id,
                        ReceiverId = uid,
                    };
                    larTalkList.Id = this._larTalkListService.InsertReturnIdentity(larTalkList);
                    model.LarTalkList = larTalkList;
                }
                else
                {
                    model.LarTalkList.IsDelete = 0;
                    this._larTalkListService.Update(model.LarTalkList);
                }
                LarTalkRecordsDto data = this._mapper.Map<LarTalkRecordsDto>(model);
                await this._hubContext.Clients.Client(connectionId).SendAsync("event_talk", data);
            }
            if (model.Id > 0)
            {
                return new MessageModel<object>()
                {
                    Code = 200,
                    Data = new
                    {
                        Id = model.Id,
                    },
                };
            }
            else
            {
                return new MessageModel<object>() { Code = 305 };
            }
        }

        /// <summary>
        /// 发送聊天文件服务接口
        /// </summary>
        [HttpPost("message/file")]
        public async Task<MessageModel<object>> File([FromBody] TalkFileParam param)
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 发送代码块消息接口  
        /// </summary>
        [HttpPost("message/code")]
        public async Task<MessageModel<object>> Code([FromBody] TalkCodeParam param)
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 发送表情包消息接口   
        /// </summary>
        [HttpPost("message/emoticon")]
        public async Task<MessageModel<object>> Emoticon([FromBody] TalkEmoticonParam param)
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 撤回聊天记录接口   
        /// </summary>
        [HttpPost("message/revoke")]
        public async Task<MessageModel<object>> Revoke()
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 发送图片消息接口  
        /// </summary>
        [HttpPost("message/image")]
        public async Task<MessageModel<object>> Image()
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 收藏聊天图片接口  
        /// </summary>
        [HttpPost("message/collect")]
        public async Task<MessageModel<object>> Collect()
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 删除聊天记录接口   
        /// </summary>
        [HttpPost("message/delete")]
        public async Task<MessageModel<object>> Delete()
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 转发聊天记录接口   
        /// </summary>
        [HttpPost("message/forward")]
        public async Task<MessageModel<object>> Forward()
        {
            return new MessageModel<object>() { };
        }
        #endregion
        #region 聊天记录相关

        /// <summary>
        /// 获取历史聊天记录.
        /// </summary>
        [HttpGet("find-chat-records")]
        public async Task<MessageModel<object>> FindChatRecords([FromQuery] string source, string receive_id, string record_id, string msg_type)
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 获取转发记录详情  
        /// </summary>
        [HttpGet("get-forward-records")]
        public async Task<MessageModel<object>> GetForwardRecords([FromQuery] int record_id)
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 获取对话面板中的聊天记录接口.   
        /// </summary>
        [HttpGet("records")]
        public async Task<MessageModel<object>> Records([FromQuery] int record_id, int receive_id, int source)//[FromBody] TalkRecordsParam param )
        {
            int receiver_Id = receive_id;
            int talk_Type = source;

            if (receiver_Id == 0 || talk_Type == 0) return new MessageModel<object> { Code = 305, Message = "参数有误！" };

            var list = await this._larTalkRecordsService.GetRecordsList(talk_Type, receiver_Id, record_id);
            list = list.Distinct().Take(10).ToList();
            return new MessageModel<object>()
            {
                Code = 200,
                Message = "success",
                Data = new
                {
                    rows = list,
                    record_id = list.LastOrDefault()?.Id,
                    limit = 10,
                },
            };
        }

        /// <summary>
        /// 获取投票记录详情.   
        /// </summary>
        [HttpGet("get-vote-detail")]
        public async Task<MessageModel<object>> GetVoteDetail([FromQuery] int record_id)
        {
            return new MessageModel<object>() { };
        }
        #endregion

        /// <summary>
        /// 获取对话列表 
        /// </summary>
        [HttpGet("list")]
        public async Task<MessageModel<List<LarTalkListDto>>> List()
        {
            int uid = this._larUsersService.GetUserId();
            List<LarTalkList> list = await this._larTalkListService.GetTalkListAsync(
                x => x.UserId == uid && x.IsDelete == 0);
            List<LarTalkListDto> dtoList = this._mapper.Map<List<LarTalkListDto>>(list);
            dtoList.ForEach(item =>
            {
                item.Online = !string.IsNullOrEmpty(this._cache.Get("re_" + item.Receiver_Id).ObjToString());
            });
            return new MessageModel<List<LarTalkListDto>>()
            {
                Code = 200,
                Message = "success",
                Data = dtoList,
            };
        }

        /// <summary>
        /// 新增对话列表  
        /// </summary>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        [HttpPost("create")]
        public async Task<MessageModel<object>> Create([FromBody] TalkCreateParam param)
        {
            if (param.Receiver_Id == 0) return new MessageModel<object>() { Code = 305 };
            int uid = this._larUsersService.GetUserId();
            var model = await this._larTalkListService.GetSingleAsync(x => x.UserId == uid && x.ReceiverId == param.Receiver_Id && x.TalkType == param.Talk_Type);
            if (model != null) // 回复 携带聊天记录
            {
                model.UpdatedAt = DateTime.Now;
                model.IsDelete = 0;
                if (this._larTalkListService.Update(model))
                {
                    var list = await this._larTalkRecordsService.GetRecordsList(model.TalkType, model.ReceiverId, 0);
                    list = list.Distinct().Take(10).ToList();
                    return new MessageModel<object>()
                    {
                        Code = 200,
                        Data = new
                        {
                            TalkItem = list,
                        },
                    };
                }
            }
            else// 直接新增
            {
                model = new LarTalkList()
                {
                    TalkType = param.Talk_Type > 0 ? param.Talk_Type : (byte)1,
                    UserId = uid,
                    ReceiverId = param.Receiver_Id,
                };
                if (await this._larTalkListService.InsertAsync(model))
                    return this.Success();
            }
            return new MessageModel<object>()
            {
                Code = 305,
                Message = string.Empty,
            };
        }

        /// <summary>
        /// 删除对话列表 
        /// </summary>
        [HttpPost("delete")]
        public async Task<MessageModel<object>> Delete([FromBody] TalkDeleteParam param)
        {
            LarTalkList larTalkList = await this._larTalkListService.GetSingleAsync(x => x.Id == param.List_Id.ObjToInt());
            if (larTalkList == null) return this.Error();
            larTalkList.IsDelete = 1;
            if (this._larTalkListService.Update(larTalkList))
                return this.Success();
            else
                return this.Error();
        }

        /// <summary>
        /// 置顶对话列表 
        /// </summary>
        [HttpPost("topping")]
        public async Task<MessageModel<object>> Topping([FromBody] TalkToppingParam param)
        {
            LarTalkList larTalkList = await this._larTalkListService.GetSingleAsync(x => x.Id == param.List_Id.ObjToInt());
            if (larTalkList == null) return this.Error();
            larTalkList.IsTop = (byte)(param.Type % 2);
            this._larTalkListService.Update(larTalkList);
            return this.Success("success", larTalkList);
        }

        /// <summary>
        /// 设置消息免打扰状态 
        /// </summary>
        /// <returns><placeholder>A <see cref="Task"/> representing the asynchronous operation.</placeholder></returns>
        [HttpPost]
        public async Task<MessageModel<object>> Disturb([FromForm] TalkDisturbParam param)
        {
            return new MessageModel<object>() { };
        }

        /// <summary>
        /// 更新对话列表未读数 
        /// </summary>
        [HttpPost("update-unread-num")]
        public async Task<MessageModel<object>> UpdateUnreadNum([FromForm] TalkUpdateUnreadNumParam param)
        {
            int uid = this._larUsersService.GetUserId();

            // 全部已读
            this._larTalkRecordsService.Update(x => x.IsRead == 1, x => x.TalkType == param.Type && x.ReceiverId == uid && x.UserId == param. Receiver_Id);

            return this.Success();
        }
    }
}
